package cc.rengu.igas.opms.core.service.trans.common;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.UrlParamBean;
import cc.rengu.igas.opms.facade.request.ClientDataDecryptRequest;
import cc.rengu.igas.opms.facade.response.ClientDataDecryptResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.SensitiveTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.SensitiveInfoService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SensitiveInfoServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import org.apache.commons.codec.binary.Base64;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * 客户端加密数据解密服务
 * modify by wangcheng 2021-09-13
 * */
public class ClientDataDecryptService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        ClientDataDecryptRequest clientDataDecryptRequest = new ClientDataDecryptRequest();
        ConvertUtil.convertOutput(clientDataDecryptRequest);
        return clientDataDecryptRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sessionId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.HEADER_SESSION);
        ClientDataDecryptRequest clientDataDecryptRequest = (ClientDataDecryptRequest) request;
        ClientDataDecryptResponse clientDataDecryptResponse = new ClientDataDecryptResponse();

        /*获取AES密钥*/
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(AppParamConstant.DEFAULT_INSTID, OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.AES_ENC_KEY);
        if (null == sysParam || StringUtil.isEmptyOrNull(sysParam.getParamValue())) {
            rglog.debug("获取解密密钥串失败");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        rglog.info("获取的解密串为<{}>", JSON.toJSONString(sysParam));
        String encryptData = clientDataDecryptRequest.getEncryptData();
        if (!StringUtil.isEmptyOrNull(encryptData)) {
            encryptData = encryptData.replaceAll("<", "+");
            encryptData = encryptData.replaceAll("＜", "<");
        }
        rglog.debug("解密密钥：{},加密字符串:{}", sysParam.getParamValue(), encryptData);
        List<UrlParamBean> urlParamList = getDecryptList(sysParam.getParamValue(), encryptData);

        /* 将敏感信息进行脱敏后存储到用户会话中 */
        SysParam sysParamSession = sysParamService.getSysParamInfo(clientDataDecryptRequest.getHeader().getInstId(),
                OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.SESSION_EXPIRY_TIMES);
        String sessionExpiryTime = (sysParamSession == null || StringUtil.isEmptyOrNull(sysParamSession.getParamValue()))
                ? String.valueOf(OpmsParamConstant.SESSION_DEFAULT_TIMES)
                : sysParamSession.getParamValue();
        SensitiveInfoService sensitiveInfoService = new SensitiveInfoServiceImpl();
        for (UrlParamBean bean : urlParamList) {
            rglog.debug("待掩码的字段:<{}>,掩码前的值:<{}>", bean.getParamKey(), bean.getParamValue());
            if ("payAcctNo".equals(bean.getParamKey())) {
                Map<String, String> sensitiveInfoMap = sensitiveInfoService.desensitise(bean.getParamKey(), bean.getParamValue(), SensitiveTypeEnum.BANK_CARD.getType(), sessionId, sessionExpiryTime);
                bean.setParamValue(sensitiveInfoMap.get(bean.getParamKey()));
            } else if ("certNo".equals(bean.getParamKey())) {
                Map<String, String> sensitiveInfoMap = sensitiveInfoService.desensitise(bean.getParamKey(), bean.getParamValue(), SensitiveTypeEnum.CERT_NO.getType(), sessionId, sessionExpiryTime);
                bean.setParamValue(sensitiveInfoMap.get(bean.getParamKey()));
            } else if ("cardHoldName".equals(bean.getParamKey())) {
                Map<String, String> sensitiveInfoMap = sensitiveInfoService.desensitise(bean.getParamKey(), bean.getParamValue(), SensitiveTypeEnum.CUSTOMER_NAME.getType(), sessionId, sessionExpiryTime);
                bean.setParamValue(sensitiveInfoMap.get(bean.getParamKey()));
            }
            rglog.debug("待掩码的字段:<{}>,掩码得到的结果:<{}>", bean.getParamKey(), bean.getParamValue());
        }

        clientDataDecryptResponse.setUrlParamList(urlParamList);
        BizResponse bizResponse = new BizResponse();
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(clientDataDecryptResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        ClientDataDecryptResponse clientDataDecryptResponse = (ClientDataDecryptResponse) bizResponse.getResult();
        ConvertUtil.convertInput(clientDataDecryptResponse);
    }

    /**
     * URL加密信息解密
     *
     * @param ketStr      解密密钥
     * @param encryptData 加密字符串
     * @return URL参数列表
     * @throws Exception 异常
     */
    private List<UrlParamBean> getDecryptList(String ketStr, String encryptData) throws Exception {
        List<UrlParamBean> urlParamBeans = new ArrayList<>();
        String urlDecoderData = URLDecoder.decode(encryptData, "UTF-8");
        String dataStr = AESUtil.pkcs7CbcDecryptData(Base64.decodeBase64(ketStr), Base64.decodeBase64(urlDecoderData));
        if (StringUtil.isEmptyOrNull(dataStr)) {
            rglog.debug("数据解密异常");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        /*解析字符串*/
        String[] tempArray = dataStr.split("&");
        Map<String, String> fieldMap = new HashMap<>();
        for (String item : tempArray) {
            if (!StringUtil.isEmptyOrNull(item)) {
                UrlParamBean urlParamBean = new UrlParamBean();
                int index = item.indexOf("=");
                String key = item.substring(0, index).trim();
                String value = item.substring(index + 1).trim();
                if (key.startsWith("/?")) {
                    urlParamBean.setParamKey(key.substring(OpmsParamConstant.INT_TWO));
                    urlParamBean.setParamValue(value);
                } else {
                    urlParamBean.setParamKey(key);
                    urlParamBean.setParamValue(value);
                }
                urlParamBeans.add(urlParamBean);
            }
        }
        return urlParamBeans;
    }
}
